﻿namespace CreaterPattern
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }

    #region 单例模式
    /// <summary>
    /// 单例模式 
    /// 描述：确保一个类只有一个实例，并提供一个全局访问点来访问该实例。
    /// 用法：当你需要对某个对象提供单一的全局访问点时（例如配置管理器和日志记录器）
    /// </summary>
    public class Singleton
    {
        private static readonly Singleton _instance = new Singleton();
        private Singleton() { }
        public static Singleton Instance => _instance;
    }
    public sealed class Logger
    {
        private static readonly Logger instance = new Logger();
        private Logger()
        {
            // 私有构造函数，防止直接实例化
        }

        public static Logger Instance => instance;
        public void Log(string message)
        {
            // 日志记录逻辑
            Console.WriteLine(message);
        }
    }
    #endregion

    #region 工厂模式
    /// <summary>
    /// 工厂模式
    /// 描述：提供一个用于创建对象的接口，同时允许子类改变将要创建的对象类型。
    /// 用法：当你需要创建对象，但不想向客户端暴露创建逻辑时，或者当你想提供一个创建相关对象却又不指定其具体类的方式时，该模式很有帮助
    /// </summary>
    public interface IProduct
    {
        void DoSomething();
    }
    public class ProductA : IProduct
    {
        public void DoSomething()
        {
            Console.WriteLine("Product A");
        }
    }
    public class ProductB : IProduct
    {
        public void DoSomething()
        {
            Console.WriteLine("Product B");
        }
    }
    public class ProductFactory 
    {
        public static IProduct CreateProduct(string type) 
        {
            return type switch
            {
                "A" => new ProductA(),
                "B" => new ProductB(),
                _ => throw new ArgumentException("Invalid type"),
            };
        }
    }


    public interface IDatabaseConnection 
    {
        void Connect();
    }
    public class SqlServerConnection : IDatabaseConnection 
    {
        public void Connect() 
        {
            // SQL Server连接逻辑
        }
    }
    public class MySqlConnection : IDatabaseConnection 
    {
        public void Connect() 
        {
            // MySql 连接逻辑
        }
    }
    public static class DatabaseConnectionFactory
    {
        public static IDatabaseConnection CreateConnection(string provider)
        {
            if (provider == "SqlServer")
                return new SqlServerConnection();
            else if (provider == "MySql")
                return new MySqlConnection();
            else
                throw new ArgumentException("Invalid provider");
        }
    }
    #endregion

    #region 适配器模式
    /// <summary>
    /// 适配器模式
    /// 描述：将一个类的接口转换为客户端期望的另一个接口。允许接口不兼容的类协同工作
    /// 用法：当你有一个类需要与另一个类交互，但接口不匹配时很有用。适配器模式可用于弥合两者之间的差距。
    /// 示例：一个适配器类，允许在应用程序种使用第三方日志记录库
    /// </summary>
    public class ThirdPartyLogger 
    {
        public void LogMessage(string message) 
        {
            // 第三方日志记录逻辑
            Console.WriteLine($"Third-Party Logger: {message}");
        }
    }
    public class LoggerAdapter : ILogger 
    {
        private readonly ThirdPartyLogger _thirdPartyLogger;
        public LoggerAdapter(ThirdPartyLogger thirdPartyLogger) 
        {
            _thirdPartyLogger = thirdPartyLogger;
        }
        public void Log(string message) 
        {
            _thirdPartyLogger.LogMessage(message);
        }
    }
    public interface ILogger 
    {
        void Log(string message);
    }
    #endregion

    #region 观察者模式
    /// <summary>
    /// 观察者模式
    /// 描述：定义对象之间的一对多依赖关系，以便当一个对象状态改变时，所有依赖它的对象都会自动收到通知并更新
    /// 用法：在需要当另一个对象的状态改变时更新多个依赖对象的场景中很有帮助，例如在事件驱动编程或发布-订阅模型中。
    /// </summary>
    public class Subject 
    {
        private readonly List<IObserver> _observers = new List<IObserver>();
        public void Attach(IObserver observer) => _observers.Add(observer);
        public void Notify() => _observers.ForEach(o => o.Update());
    }
    public interface IObserver 
    {
        void Update();
    }
    public class ConcreteObserver : IObserver 
    {
        public void Update()
        {
            Console.WriteLine("Observer updated!");
        }
    }
    #endregion

    #region 装饰器模式
    /// <summary>
    /// 装饰器模式
    /// 描述：动态地给对象附加额外的职责。装饰器为扩展功能提供了一种比继承更灵活的替代方案
    /// 用法：当你需要在运行时给对象添加或移除职责，且不影响对象的核心功能时很有用
    /// </summary>
    #endregion

    #region 命令模式
    /// <summary>
    /// 命令模式
    /// 描述：将请求封装为一个对象，从而允许使用不同请求对客户端进行参数化、对请求进行排队或记录日志，并支持可撤销操作
    /// 用法：在需要将操作的调用者与执行操作的对象分离的场景中很有帮助，例如在撤销\重做功能或事件驱动架构中
    /// </summary>
    #endregion

    #region 仓储模式
    /// <summary>
    /// 仓储模式
    /// 描述：在应用程序的数据访问层和业务逻辑层之间提供一个抽象层
    /// 用法：有助于以一种独立于底层数据源的方法管理数据访问，使得在不同数据源之间切换或测试应用程序的数据访问逻辑更加容易。
    /// </summary>
    public interface IRepository<T> 
    {
        IEnumerable<T> GetAll();
        void Add(T item);
    }

    public class InMemoryRepository<T> : IRepository<T> 
    {
        private readonly List<T> _items = new List<T>();

        public IEnumerable<T> GetAll() => _items;
        public void Add(T item) => _items.Add(item);
    }
    #endregion

    #region 策略模式
    public interface IStrategy 
    {
        int Execute(int a, int b);
    }

    public class Addition : IStrategy 
    {
        public int Execute(int a, int b) => a + b;
    }
    public class Subtraction : IStrategy 
    {
        public int Execute(int a, int b) => a - b;
    }

    public class Context 
    {
        private IStrategy _strategy;

        public void SetStrategy(IStrategy strategy) => _strategy = strategy;
        public int ExecuteStrategy(int a, int b) => _strategy.Execute(a, b);
    }
    #endregion
}
